/*
 * @(#)ControlImpl.java	1.0 2000/12/30
 *
 * Copyright 2000 Thomas Barnekow. All Rights Reserved.
 *
 * This software is the proprietary information of Thomas Barnekow.
 * Use is subject to license terms.
 */

package tb.jots.impl;

import java.util.*;
import tb.jots.*;

/**
 * {@link Control} implementation.
 *
 * @author Thomas Barnekow
 * @version 1.0
 */
public class ControlImpl implements Control {

  /**
   * This {@link Collection} contains {@link Current} objects connected to this
   * {@link Control} instance.
   */
  Collection m_currentCollection;

  /**
   * The {@link Terminator} reference.
   */
  Terminator m_terminator;

  /**
   * The {@link Coordinator} reference.
   */
  Coordinator m_coordinator;

  /**
   * Create a {@link Control} instance.
   */
  ControlImpl() {
    m_currentCollection = Collections.synchronizedCollection(new HashSet());
    m_terminator = new TerminatorImpl(this);
    m_coordinator = new CoordinatorImpl(this);
  }

	public Terminator getTerminator() throws UnavailableException {
    if (m_terminator == null)
      throw new UnavailableException();
    else
      return m_terminator;
  }

	public Coordinator getCoordinator() throws UnavailableException {
    if (m_coordinator == null)
      throw new UnavailableException();
    else
      return m_coordinator;
  }

	/*
   * Implementation-specific operations
   */

  boolean addCurrent(CurrentImpl current) {
    return m_currentCollection.add(current);
  }

  boolean removeCurrent(CurrentImpl current) {
    return m_currentCollection.remove(current);
  }

  void resetTransactionContext() {
    // Reset Current contexts
    if (m_currentCollection != null) {
      Iterator iterator = m_currentCollection.iterator();
      while (iterator.hasNext()) {
        CurrentImpl current = (CurrentImpl) iterator.next();
        current.resetTransactionContext();
      }
    }

    // Reset own (Control) context
    m_currentCollection = null;
    m_terminator = null;
    m_coordinator = null;
	}

  void checkCallingThread() throws NoPermissionException {
    Control threadControl = CurrentImpl.getCurrent().getControl();
    if (threadControl == null || !threadControl.equals(this))
      throw new NoPermissionException();
  }
}